<template>
  <div class="card mb-5">
    <h2 class="text-2xl mb-5">📤 创建新任务</h2>

    <!-- Tab Navigation -->
    <div class="mb-5">
      <div class="flex border-b border-gray-300 mb-4">
        <button
          :class="['px-5 py-2.5 bg-gray-100 cursor-pointer border-0 border-b-2 border-transparent mr-2.5 rounded-t transition-all', activeTab === 'upload' ? 'bg-white border-b-blue-600 text-blue-600 font-bold' : 'text-gray-600 hover:bg-gray-200']"
          @click="switchTab('upload')"
        >
          上传图片
        </button>
        <button
          :class="['px-5 py-2.5 bg-gray-100 cursor-pointer border-0 border-b-2 border-transparent mr-2.5 rounded-t transition-all', activeTab === 's3select' ? 'bg-white border-b-blue-600 text-blue-600 font-bold' : 'text-gray-600 hover:bg-gray-200']"
          @click="switchTab('s3select')"
        >
          选择S3图片
        </button>
      </div>

      <!-- Upload Tab -->
      <div v-show="activeTab === 'upload'">
        <div
          :class="['border-2 border-dashed rounded-lg p-5 text-center cursor-pointer transition-colors mb-4', isDragOver ? 'border-blue-600 bg-gray-100' : 'border-gray-300 hover:border-blue-600']"
          @click="triggerFileInput"
          @dragover.prevent="handleDragOver"
          @drop.prevent="handleDrop"
          @dragleave="handleDragLeave"
        >
          <div class="text-5xl mb-2.5 text-gray-600">📁</div>
          <div class="mb-2.5 text-gray-600">点击选择图片或拖拽图片到这里</div>
          <small>支持 JPG、PNG、JPEG 格式</small>
          <input
            ref="fileInput"
            type="file"
            class="hidden"
            accept="image/*"
            @change="handleFileSelect"
          />
        </div>

        <div v-if="selectedFile" class="mt-4 p-2.5 border border-gray-300 rounded bg-gray-100">
          <div class="flex items-center gap-2.5">
            <img :src="selectedFilePreview" alt="预览" class="max-w-[100px] max-h-[100px] rounded" />
            <div>
              <div><strong>已选择:</strong> {{ selectedFile.name }}</div>
              <div><small>大小: {{ formatFileSize(selectedFile.size) }}</small></div>
            </div>
            <button @click="clearFileSelection" class="ml-auto px-2.5 py-1.5 bg-red-500 text-white rounded hover:bg-red-600">
              ✕
            </button>
          </div>
        </div>
      </div>

      <!-- S3 Select Tab -->
      <div v-show="activeTab === 's3select'">
        <div class="mb-4">
          <label for="s3ImageSelect" class="block mb-1.5 font-bold">选择S3图片:</label>
          <select
            id="s3ImageSelect"
            v-model="selectedS3ImageKey"
            @change="handleS3ImageSelect"
            class="input-field"
          >
            <option value="">
              {{ s3ImagesLoading ? '正在加载图片列表...' : (s3Images.length > 0 ? '请选择图片...' : '未找到图片文件') }}
            </option>
            <option v-for="image in s3Images" :key="image.key" :value="image.key">
              {{ image.filename }} ({{ image.size }})
            </option>
          </select>
        </div>

        <div v-if="selectedS3Image" class="mt-4 p-2.5 border border-gray-300 rounded bg-gray-100">
          <div class="flex items-center gap-2.5">
            <img :src="replaceImageUrl(selectedS3Image.url)" alt="预览" class="max-w-[100px] max-h-[100px] rounded" @error="hideImageOnError" />
            <div>
              <div><strong>已选择:</strong> {{ selectedS3Image.filename }}</div>
              <div><small>大小: {{ selectedS3Image.size }}</small></div>
              <div><small>路径: {{ selectedS3Image.key }}</small></div>
              <div><small>最后修改: {{ formatDate(selectedS3Image.last_modified) }}</small></div>
            </div>
            <button @click="clearS3Selection" class="ml-auto px-2.5 py-1.5 bg-red-500 text-white rounded hover:bg-red-600">
              ✕
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- Parameters -->
    <div class="grid grid-cols-1 md:grid-cols-2 gap-2.5 my-2.5">
      <div class="border border-gray-300 rounded-lg p-2.5 bg-gray-100">
        <h4 class="mt-0 mb-4 text-gray-800 border-b border-gray-300 pb-2">🟢 零件检测参数</h4>
        <div class="flex items-center justify-between mb-2.5">
          <label class="m-0 text-sm min-w-[120px]">置信度阈值:</label>
          <input type="number" v-model.number="taskParams.part.conf_threshold" min="0.05" max="1" step="0.05" class="w-20 px-2 py-1 border border-gray-300 rounded text-sm" />
        </div>
        <div class="flex items-center justify-between mb-2.5">
          <label class="m-0 text-sm min-w-[120px]">IoU阈值:</label>
          <input type="number" v-model.number="taskParams.part.iou_threshold" min="0" max="1" step="0.05" class="w-20 px-2 py-1 border border-gray-300 rounded text-sm" />
        </div>
        <div class="flex items-center justify-between mb-2.5">
          <label class="m-0 text-sm min-w-[120px]">最小面积:</label>
          <input type="number" v-model.number="taskParams.part.min_area" min="0" step="1" class="w-20 px-2 py-1 border border-gray-300 rounded text-sm" />
        </div>
      </div>

      <div class="border border-gray-300 rounded-lg p-2.5 bg-gray-100">
        <h4 class="mt-0 mb-4 text-gray-800 border-b border-gray-300 pb-2">🔵 钢印检测参数</h4>
        <div class="flex items-center justify-between mb-2.5">
          <label class="m-0 text-sm min-w-[120px]">置信度阈值:</label>
          <input type="number" v-model.number="taskParams.steel_stamp.conf_threshold" min="0" max="1" step="0.05" class="w-20 px-2 py-1 border border-gray-300 rounded text-sm" />
        </div>
        <div class="flex items-center justify-between mb-2.5">
          <label class="m-0 text-sm min-w-[120px]">IoU阈值:</label>
          <input type="number" v-model.number="taskParams.steel_stamp.iou_threshold" min="0" max="1" step="0.05" class="w-20 px-2 py-1 border border-gray-300 rounded text-sm" />
        </div>
      </div>

      <div class="border border-gray-300 rounded-lg p-2.5 bg-gray-100">
        <h4 class="mt-0 mb-4 text-gray-800 border-b border-gray-300 pb-2">🔴 镭雕检测参数</h4>
        <div class="flex items-center justify-between mb-2.5">
          <label class="m-0 text-sm min-w-[120px]">置信度阈值:</label>
          <input type="number" v-model.number="taskParams.laser_engraving.conf_threshold" min="0" max="1" step="0.05" class="w-20 px-2 py-1 border border-gray-300 rounded text-sm" />
        </div>
        <div class="flex items-center justify-between mb-2.5">
          <label class="m-0 text-sm min-w-[120px]">IoU阈值:</label>
          <input type="number" v-model.number="taskParams.laser_engraving.iou_threshold" min="0" max="1" step="0.05" class="w-20 px-2 py-1 border border-gray-300 rounded text-sm" />
        </div>
      </div>

      <div class="border border-gray-300 rounded-lg p-2.5 bg-gray-100">
        <h4 class="mt-0 mb-4 text-gray-800 border-b border-gray-300 pb-2">🟡 R角检测参数</h4>
        <div class="flex items-center justify-between mb-2.5">
          <label class="m-0 text-sm min-w-[120px]">置信度阈值:</label>
          <input type="number" v-model.number="taskParams.r_corner.conf_threshold" min="0" max="1" step="0.05" class="w-20 px-2 py-1 border border-gray-300 rounded text-sm" />
        </div>
        <div class="flex items-center justify-between mb-2.5">
          <label class="m-0 text-sm min-w-[120px]">IoU阈值:</label>
          <input type="number" v-model.number="taskParams.r_corner.iou_threshold" min="0" max="1" step="0.05" class="w-20 px-2 py-1 border border-gray-300 rounded text-sm" />
        </div>
      </div>
    </div>

    <button @click="createTask" :disabled="isCreatingTask" class="btn-primary">
      {{ createTaskBtnText }}
    </button>
  </div>
</template>

<script>
export default {
  name: 'TaskCreation',
  data() {
    return {
      activeTab: 'upload',
      isDragOver: false,
      selectedFile: null,
      selectedFilePreview: '',
      s3Images: [],
      s3ImagesLoading: false,
      selectedS3ImageKey: '',
      selectedS3Image: null,
      taskParams: {
        part: {
          conf_threshold: 0.8,
          iou_threshold: 0,
          min_area: 0
        },
        steel_stamp: {
          conf_threshold: 0.8,
          iou_threshold: 0
        },
        laser_engraving: {
          conf_threshold: 0.8,
          iou_threshold: 0
        },
        r_corner: {
          conf_threshold: 0.8,
          iou_threshold: 0
        }
      },
      isCreatingTask: false,
      createTaskBtnText: '🚀 创建任务',
      baseUrl: 'http://k396a3ad.natappfree.cc',
      apiUrl: 'https://demo-1abed178a906e331.clonebot.work/detection-predict-api'
    }
  },
  created() {
    this.restoreConfiguration()
  },
  methods: {
    switchTab(tabName) {
      this.activeTab = tabName
      if (tabName === 's3select') {
        this.loadS3Images()
      }
    },
    triggerFileInput() {
      this.$refs.fileInput.click()
    },
    handleDragOver() {
      this.isDragOver = true
    },
    handleDragLeave() {
      this.isDragOver = false
    },
    handleDrop(event) {
      this.isDragOver = false
      const files = event.dataTransfer.files
      if (files.length > 0) {
        this.processFileSelection(files[0])
      }
    },
    handleFileSelect(event) {
      const file = event.target.files[0]
      if (file) {
        this.processFileSelection(file)
      }
    },
    processFileSelection(file) {
      if (!file.type.startsWith('image/')) {
        alert('请选择图片文件')
        return
      }
      this.selectedFile = file
      this.selectedS3Image = null
      this.selectedS3ImageKey = ''
      const reader = new FileReader()
      reader.onload = (e) => {
        this.selectedFilePreview = e.target.result
      }
      reader.readAsDataURL(file)
    },
    clearFileSelection() {
      this.selectedFile = null
      this.selectedFilePreview = ''
      this.$refs.fileInput.value = ''
    },
    async loadS3Images() {
      if (this.s3Images.length > 0) return
      this.s3ImagesLoading = true
      try {
        const response = await fetch(`${this.apiUrl}/api/list_images?prefix=uploads&limit=100`)
        if (response.ok) {
          const data = await response.json()
          if (data.success && data.images && data.images.length > 0) {
            this.s3Images = data.images.map(image => ({
              ...image,
              url: this.replaceImageUrl(image.url)
            }))
          }
        }
      } catch (error) {
        console.error('Error loading S3 images:', error)
      } finally {
        this.s3ImagesLoading = false
      }
    },
    handleS3ImageSelect() {
      if (!this.selectedS3ImageKey) {
        this.clearS3Selection()
        return
      }
      const image = this.s3Images.find(img => img.key === this.selectedS3ImageKey)
      if (image) {
        this.selectedS3Image = image
        this.selectedFile = null
        this.selectedFilePreview = ''
      }
    },
    clearS3Selection() {
      this.selectedS3Image = null
      this.selectedS3ImageKey = ''
    },
    async createTask() {
      if (!this.selectedFile && !this.selectedS3Image) {
        alert('请先选择图片（上传文件或从S3选择）')
        return
      }
      this.isCreatingTask = true
      this.createTaskBtnText = '⏳ 创建中...'
      try {
        let response
        if (this.selectedFile) {
          this.createTaskBtnText = '📤 上传中...'
          const uploadFormData = new FormData()
          uploadFormData.append('file', this.selectedFile)
          const uploadResponse = await fetch(`${this.apiUrl}/api/upload`, {
            method: 'POST',
            body: uploadFormData
          })
          if (!uploadResponse.ok) {
            const uploadError = await uploadResponse.json().catch(() => ({ message: '上传失败' }))
            throw new Error(`文件上传失败: ${uploadError.message || uploadError.detail || '未知错误'}`)
          }
          const uploadResult = await uploadResponse.json()
          if (!uploadResult.success || !uploadResult.data || !uploadResult.data.url) {
            throw new Error(`文件上传失败: ${uploadResult.message || '上传结果无效'}`)
          }
          this.createTaskBtnText = '🔄 创建任务中...'
          const requestBody = {
            image_url: uploadResult.data.url,
            part_params: this.taskParams.part,
            steel_stamp_params: this.taskParams.steel_stamp,
            laser_engraving_params: this.taskParams.laser_engraving,
            r_corner_params: this.taskParams.r_corner
          }
          response = await fetch(`${this.apiUrl}/api/create_task`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(requestBody)
          })
        } else if (this.selectedS3Image) {
          const s3ImageUrl = this.replaceImageUrl(this.selectedS3Image.url) || `${this.baseUrl}/predict-images/${this.selectedS3ImageKey}`
          const requestBody = {
            image_url: s3ImageUrl,
            part_params: this.taskParams.part,
            steel_stamp_params: this.taskParams.steel_stamp,
            laser_engraving_params: this.taskParams.laser_engraving,
            r_corner_params: this.taskParams.r_corner
          }
          response = await fetch(`${this.apiUrl}/api/create_task`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(requestBody)
          })
        }
        if (response.ok) {
          const result = await response.json()
          alert(`任务创建成功！\n任务ID: ${result.task_id}\n状态: ${result.status}`)
          this.clearFileSelection()
          this.clearS3Selection()
          this.$emit('task-created', result.task_id)
        } else {
          const errorData = await response.json().catch(() => ({ error: '未知错误' }))
          alert(`创建任务失败: ${errorData.error || errorData.detail || '服务器错误'}`)
        }
      } catch (error) {
        alert(`创建任务失败: ${error.message}`)
      } finally {
        this.isCreatingTask = false
        this.createTaskBtnText = '🚀 创建任务'
      }
    },
    formatFileSize(bytes) {
      if (bytes === 0) return '0 B'
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    },
    formatDate(dateStr) {
      if (!dateStr) return '未知'
      return new Date(dateStr).toLocaleDateString()
    },
    replaceImageUrl(url) {
      if (!url || !this.baseUrl) return url
      return url.replace(/https?:\/\/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+|minio:[0-9]+)/g, this.baseUrl)
    },
    hideImageOnError(event) {
      event.target.style.display = 'none'
    },
    restoreConfiguration() {
      const savedBaseUrl = localStorage.getItem('s3BaseUrl')
      const savedApiUrl = localStorage.getItem('apiUrl')
      if (savedBaseUrl) this.baseUrl = savedBaseUrl
      if (savedApiUrl) this.apiUrl = savedApiUrl
    }
  }
}
</script>

